package com.example.event_resource_java.authority.server.resourceLibrary.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.event_resource_java.authority.dao.EventResourceAllocationDO;
import com.example.event_resource_java.authority.dao.UserDao;
import com.example.event_resource_java.authority.domain.resourceLibrary.SecretAssets;
import com.example.event_resource_java.authority.domain.resourceLibrary.SecretKey;
import com.example.event_resource_java.authority.mapper.resourceLibrary.SecretKeyMapper;
import com.example.event_resource_java.authority.server.ResourceServer;
import com.example.event_resource_java.authority.server.UserServer;
import com.example.event_resource_java.authority.server.resourceLibrary.SecretAssetsService;
import com.example.event_resource_java.authority.server.resourceLibrary.SecretKeyService;
import com.example.event_resource_java.commons.domain.UserDO;
import com.example.event_resource_java.commons.util.ApiResult;
import com.example.event_resource_java.commons.util.JWTUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * (SecretKey)表服务实现类
 *
 * @author makejava
 * @since 2024-05-09 10:24:38
 */
@Service
public class SecretKeyServiceImpl extends ServiceImpl<SecretKeyMapper, SecretKey> implements SecretKeyService, IService<SecretKey> {


    private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    /**
     * 资源秘钥关联业务
     */
    private final SecretAssetsService secretAssetsDao;

    /**
     * 资源信息
     */
    private final SecretKeyMapper secretKeyDao;

    /**
     * 用户
     * @param secretAssetsDao
     */
    private final UserDao userdao;

    /**
     * 资源信息
     */
    private final ResourceServer eventresourceAllocationService;

    @Resource
    private UserServer userServer;


    public SecretKeyServiceImpl(SecretAssetsService secretAssetsDao, SecretKeyMapper secretKeyDao, UserDao userdao, ResourceServer eventresourceAllocationService) {
        this.secretAssetsDao = secretAssetsDao;
        this.secretKeyDao = secretKeyDao;
        this.userdao = userdao;
        this.eventresourceAllocationService = eventresourceAllocationService;
    }

    @Override
    public ApiResult saveSecretKey(SecretKey secretKey) {
        secretKey.setSecretKey(generateKey(20));
        Boolean aBoolean = this.save(secretKey);
        if(secretKey.getSecretAssets() == null || secretKey.getSecretAssets().isEmpty()){
            return ApiResult.success(aBoolean);
        }
        //资源信息不为null
        secretKey.getSecretAssets().forEach(a->{
            a.setSecretId(secretKey.getId());
        });
        return ApiResult.success(secretAssetsDao.saveBatch(secretKey.getSecretAssets()));
    }

    public static String generateKey(int length) {
        StringBuilder sb = new StringBuilder(length);
        SecureRandom secureRandom = new SecureRandom();
        for (int i = 0; i < length; i++) {
            int index = secureRandom.nextInt(ALPHA_NUMERIC_STRING.length());
            sb.append(ALPHA_NUMERIC_STRING.charAt(index));
        }
        return sb.toString();
    }

    @Override
    @Transactional
    public ApiResult editSecretKey(SecretKey secretKey) {
        //修改秘钥信息
        Boolean aBoolean = this.updateById(secretKey);
        if (secretKey.getSecretAssets() == null || secretKey.getSecretAssets().isEmpty()) {
            return ApiResult.success(aBoolean);
        }
        //删除资源信息
        secretAssetsDao.remove(new QueryWrapper<SecretAssets>().eq("secret_id",secretKey.getId()));
        //新增资源信息
        //资源信息不为null
        secretKey.getSecretAssets().forEach(a->{
            a.setSecretId(secretKey.getId());
        });
        return ApiResult.success(secretAssetsDao.saveBatch(secretKey.getSecretAssets()));
    }

    @Override
    public ApiResult getSecretKyPage(SecretKey secretKey) {

        Page<SecretKey> page = new Page<SecretKey>(secretKey.getCurrent(),secretKey.getSize());
        IPage<SecretKey> secretKeyPage = this.page(page,new QueryWrapper<SecretKey>()
                .eq(Objects.nonNull(secretKey.getStatus()),"status",secretKey.getStatus())
                .like(Objects.nonNull(secretKey.getSecretKey()),"secret_key",secretKey.getSecretKey()));
        if(secretKeyPage.getRecords().isEmpty()){
            return ApiResult.success(secretKeyPage);
        }
        //拿到使用人id集合
        List<Long> ids = secretKeyPage.getRecords().stream().map(SecretKey::getUserId).collect(Collectors.toList());
        List<UserDO> userDOS = userdao.selectList(new QueryWrapper<UserDO>().in("id",ids));
        if(userDOS.isEmpty()){
            return ApiResult.success(secretKeyPage);
        }
        secretKeyPage.getRecords().forEach(a-> userDOS.forEach(b->{
            if(Objects.equals(a.getUserId(),b.getId())){
                a.setUserName(b.getUsername());
            }
        }));
        return ApiResult.success(secretKeyPage);
    }

    @Override
    public SecretKey getSecretKy(Long id) {
        //根据秘钥id获取秘钥信息
        SecretKey secretKey = this.getById(id);
        //获取使用人名称
        secretKey.setUserName(userdao.selectById(secretKey.getUserId()).getName());
        //获取所有资源信息
        List<EventResourceAllocationDO> evens = eventresourceAllocationService.evens();
        if(evens.isEmpty()){
            return secretKey;
        }
        //获取秘钥关联资源信息
        List<SecretAssets> secretAssets = secretAssetsDao.list(new QueryWrapper<SecretAssets>().eq("secret_id",id));
        //没有相关资源不做后续算法
        if(secretAssets.isEmpty()){
            Map<String,List<EventResourceAllocationDO>> map = evens.stream().collect(Collectors.groupingBy(EventResourceAllocationDO::getEveMoName));
            secretKey.setEventrMap(map);
            return secretKey;
        }
        //对比是否已有资源，以后资源该状态为已选择
        evens.forEach(a -> secretAssets.forEach(b->{
            if(Objects.equals(a.getId(),b.getAllocationId())){
                a.setIsShow(1);
            }
        }));
        Map<String,List<EventResourceAllocationDO>> map = evens.stream().collect(Collectors.groupingBy(EventResourceAllocationDO::getEveMoName));
        secretKey.setEventrMap(map);
        return secretKey;
    }



    @Override
    public Map<String,List<EventResourceAllocationDO>> getAddSecretKy() {
        Map<String,List<EventResourceAllocationDO>> map = new HashMap<>();
        //获取所有资源信息
        List<EventResourceAllocationDO> evens = eventresourceAllocationService.evens();
        if(evens.isEmpty()){
            return map;
        }
        map = evens.stream().collect(Collectors.groupingBy(EventResourceAllocationDO::getEveMoName));
        return map;
    }


    @Override
    public void timingEffect() {
        //查询所有时效秘钥
        List<SecretKey>  secretKeys = this.list(new QueryWrapper<SecretKey>().eq("type",1));
        if(secretKeys.isEmpty()){
            return;
        }
        //获取所有时间已过期的秘钥并改变状态为已过期
        secretKeys = secretKeys.stream().filter(a -> !LocalDateTime.now().isBefore(a.getExpirationDate())).peek(b -> b.setStatus(2)).collect(Collectors.toList());
        //验证是否有已过期的秘钥
        if(secretKeys.isEmpty()){
            return;
        }
        this.updateBatchById(secretKeys);
    }

    @Override
    public ApiResult removeById(Long id) {
        secretKeyDao.deleteById(id);
        return ApiResult.success(secretAssetsDao.remove(new QueryWrapper<SecretAssets>().eq("secret_id",id)));
    }

    @Override
    public Boolean permissionVerification(Long allocationId) {
        Long userId = JWTUtil.getUser().getId();

        QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
        userDOQueryWrapper.eq("id", userId);
        UserDO userDO = userServer.getOne(userDOQueryWrapper);

        Integer type = userDO.getType();
        Boolean ab = false;
        //获取用户类型
        if(Objects.isNull(type)){
            return ab;
        }

        LocalDateTime now = LocalDateTime.now();
        //1==教师
        if(type == 1){
            if(!this.baseMapper.isAssets(userId,allocationId,now).isEmpty()){
                ab = true;
            }
            return ab;
        }

        //0==学生,获取教师id
        Long id = this.baseMapper.getTeacherById(userId);
        if(Objects.isNull(id)){
            return ab;
        }
        if(type == 0){
            if(!this.baseMapper.isAssets(id,allocationId,now).isEmpty()){
                ab = true;
            }
            return ab;
        }
        return ab;
    }

    @Override
    public Boolean purchaseAll() {
        // TODO
        return null;
    }


}

